import pygame
import pygame.cursors
import sys
import tkinter as tk
from button_menu_fuction import *
from game_sprites import *
from pygame.locals import *
from button_menu_fuction import *
SMALL_COUNTS=2
MID_COUNTS=1
BIG_COUNTS=1
BOSS_FIRE_BULLET=pygame.USEREVENT+4
SMALL_SCORE=5
MID_SCORE=10
BIG_SCORE=15

BLACK = (0,0,0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
WHITE = (255,255,255)
BOSS_BULLET_TIME=1000


class Game_Main():
    def __init__(self,level=1):
        pygame.init()
        self.level=level
        self.score=0
        self.isLevel=True
        self.delay=100
        self.paused=False
        self.recorded=False
        self.record_score=0
        self.record_best_name=str()
        #1.初始化屏幕
        self.screen=pygame.display.set_mode((SCREEN_RECT.width,SCREEN_RECT.height))
        self.screen_rect=self.screen.get_rect()
        pygame.display.set_caption("飞机大战")
        self.image_protect=pygame.image.load("image/pro_cov.png")
        self.rect=self.image_protect.get_rect()
        #2.初始化游戏时钟
        self.clock=pygame.time.Clock()
        #3.创建精灵和精灵族
        self.__create_sprite()
        # 设置boss子弹发射间隔
        pygame.time.set_timer(BOSS_FIRE_BULLET, BOSS_BULLET_TIME)
        #4.设置定时器-发射子弹
        pygame.time.set_timer(FIRE_BULLET,100)

        #5.初始化加载声音文件
        # pygame.mixer.music.load("music/bgm.mp3")
        # pygame.mixer.music.set_volume(0.2)

        # self.bullet_sound = pygame.mixer.Sound("music/bullet.wav")
        # self.bullet_sound.set_volume(0.2)
        #
        # self.double_bullet_sound = pygame.mixer.Sound("music/doublebullet.wav")
        # self.double_bullet_sound.set_volume(0.3)
        #
        # self.bigdestroy_sound=pygame.mixer.Sound("music/bigdestory.wav")
        # self.bigdestroy_sound.set_volume(0.3)
        #
        # self.middestroy_sound = pygame.mixer.Sound("music/middestory.wav")
        # self.middestroy_sound.set_volume(0.3)
        #
        # self.smalldestroy_sound = pygame.mixer.Sound("music/smalldestory.wav")
        # self.smalldestroy_sound.set_volume(0.3)

        self.my_font = pygame.font.Font("font/myfont.TTF" , 40)


        self.double_bullet_image = pygame.image.load("image/bullet2.png").convert_alpha()
        self.double_bullet_image.set_alpha(160)

        stopping_img = pygame.image.load("image/stopping.png").convert_alpha()
        stopping_rect = stopping_img.get_rect()
        stopping_rect.left , stopping_rect.top = SCREEN_RECT.width // 2 - stopping_rect.width // 2 , SCREEN_RECT.height // 2 - stopping_rect.height // 2
        #########################

        self.paused_nor_image = pygame.image.load("image/pause_nor.png").convert_alpha()
        self.pause_pressed_image = pygame.image.load("image/pause_pressed.png").convert_alpha()
        self.resume_nor_image = pygame.image.load("image/resume_nor.png").convert_alpha()
        self.resume_pressed_image = pygame.image.load("image/resume_pressed.png").convert_alpha()

        self.paused_rect = self.paused_nor_image.get_rect()
        self.paused_rect.left , self.paused_rect.top = SCREEN_RECT.width - self.paused_rect.width - 50 , 50
        self.paused_image = self.pause_pressed_image



        # 游戏结束画面以及分数的预加载
        self.gameover_text1=self.my_font.render("兔子本局得分： ",True, WHITE)
        self.gameover_text1_rect = self.gameover_text1.get_rect()
        self.gameover_text1_rect.left , self.gameover_text1_rect.top = \
            (SCREEN_RECT.width - self.gameover_text1_rect.width) // 2 , SCREEN_RECT.height // 2


        self.gameover_image = pygame.image.load("image/gameover.png").convert_alpha()


        self.gameover_text2 = self.my_font.render(str(self.score) , True , WHITE)
        self.gameover_text2_rect = self.gameover_text2.get_rect()
        self.gameover_text2_rect.left , self.gameover_text2_rect.top = \
            (SCREEN_RECT.width - self.gameover_text1_rect.width) // 2 +self.gameover_text1.get_width(),\
             SCREEN_RECT.height // 2

        self.again_image = pygame.image.load("image/again.png").convert_alpha()
        self.again_rect = self.again_image.get_rect()
        self.again_rect.left , self.again_rect.top = \
            (SCREEN_RECT.width - self.again_rect.width) // 2 , \
            self.gameover_text2_rect.bottom + 50

        self.gameover_rect = self.gameover_image.get_rect()
        self.gameover_rect.left , self.gameover_rect.top = \
            (SCREEN_RECT.width - self.again_rect.width) // 2 , \
            self.again_rect.bottom + 10







    def change_level(self):
            #upgrade_sound.play()
            self.add_small_enermys(self.small_enemy_group,int(self.level+SMALL_COUNTS))
            self.add_mid_enermys(self.mid_enemy_group, int(self.level+MID_COUNTS))
            self.add_big_enermys(self.big_enemy_group,int(self.level*0.5+BIG_COUNTS))
            if self.score>=5:
                self.boss01_group.add(self.Boss)
            self.enemy_group.add(self.small_enemy_group , self.mid_enemy_group , self.big_enemy_group,self.boss01_group)


    def add_small_enermys(self,group,num):
        for i in range(num):
            Enermy=Small_enermy()
            group.add(Enermy)
    def add_mid_enermys(self,group,num):
        for i in range(num):
            Enermy=Mid_enermy()
            group.add(Enermy)

    def add_big_enermys(self , group , num) :
        for i in range(num) :
            Enermy = Big_enermy()
            group.add(Enermy)



    def __create_sprite(self):
         #背景移动精灵的创建
         bg1= Bg_Ground("image/background2.png")
         bg2=Bg_Ground("image/background.png",isAlt=True)
         self.bg_group=pygame.sprite.Group(bg1,bg2)

         # 创建双倍补给精灵组
         self.double_bullet_supply_group = pygame.sprite.Group()
         #创建炸弹补给精灵组
         self.bomb_supply_group=pygame.sprite.Group()

         #创建小型敌机
         self.small_enemy_group = pygame.sprite.Group()

         #创建中型战机
         self.mid_enemy_group = pygame.sprite.Group()


         #创建大型战机
         self.big_enemy_group = pygame.sprite.Group()

         self.enemy_group = pygame.sprite.Group()

         self.Boss=Boss1()
         self.boss01_group = pygame.sprite.Group()

         #创建我方战机
         self.rabbit = MyRabbit()
         self.myrabbit=pygame.sprite.Group()
         self.myrabbit.add(self.rabbit)

         self.gameGroup=pygame.sprite.Group()
    def start_game(self):
         while True :
            #1.设置刷新率
            self.clock.tick(70)
            #2.事件监听
            self.__event_handler()

            #3.碰撞检测
            self.__check_collide()

            #4.更新绘制精灵、精灵组
            self.__update_sprites()

            #5.更新显示
            pygame.display.flip()


    def __event_handler(self):

        for event in pygame.event.get():
            if event.type==pygame.QUIT:
                sys.exit()
            elif event.type==INVINCIBLE_TIME:
                pygame.time.set_timer(INVINCIBLE_TIME,0)
                self.rabbit.invincible=False
            elif event.type == BOSS_FIRE_BULLET and self.Boss.rect.bottom >= 360 and self.rabbit.life>0:
                self.Boss.boss_fired()
            key_pressed=pygame.key.get_pressed()
            if  event.type==FIRE_BULLET and key_pressed[pygame.K_SPACE]:
                if self.rabbit.life >= 0 and self.paused == False :
                    #self.bullet_sound.play()
                    self.rabbit.fired()


            elif key_pressed[pygame.K_m]:
                self.rabbit.isDoubleBullet=True
                self.rabbit.fired_double_bullet()
                # if self.rabbit.life >= 0 and self.paused == False :
                #     if self.rabbit.double_bullet_counts>=1:
                #        #self.double_bullet_sound.play()
            elif key_pressed[pygame.K_LALT] and key_pressed[pygame.K_F4]:
                sys.exit()


            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_b :
                    self.rabbit.isBomb = True
                    self.rabbit.fired_bomb()
                    if self.rabbit.bomb_counts>=1:
                        for e in self.enemy_group:
                            e.isDown=True

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_b :
                    self.rabbit.isBomb = False

            elif event.type == MOUSEBUTTONDOWN :
                if event.button == 1 and self.paused_rect.collidepoint(event.pos):
                    self.paused = not self.paused
                    if self.paused :
                        pygame.mixer.music.pause()
                        pygame.mixer.pause()
                        self.paused_image = self.resume_pressed_image
                    else:
                        pygame.mixer.music.unpause()
                        pygame.mixer.unpause()
                        self.paused_image = self.pause_pressed_image
            #第一种方法
                if self.rabbit.life==0:
                    if event.button == 1 and self.again_rect.collidepoint(pygame.mouse.get_pos()) :
                        again = Game_Main()
                        self.gameGroup.add(again)
                        again.start_game()
                    elif event.button == 1 and self.gameover_rect.collidepoint(pygame.mouse.get_pos()) :
                        pygame.quit()
                        sys.exit()
            #第二种方法
            # elif pygame.mouse.get_pressed()[0]:
            #     pos = pygame.mouse.get_pos()
            #     if self.again_rect.left < pos[0] < self.again_rect.right and \
            #        self.again_rect.top < pos[1] < self.again_rect.bottom:
            #        again=Game_Main()
            #        again.start_game()
            #     elif self.gameover_rect.left < pos[0] < self.gameover_rect.right and \
            #          self.gameover_rect.top < pos[1] < self.gameover_rect.bottom:
            #          pygame.quit()
            #          sys.exit()

            elif event.type == MOUSEMOTION :
                if self.paused_rect.collidepoint(event.pos) :#鼠标在暂停框内
                    if self.paused :#暂停
                        self.paused_image = self.resume_pressed_image
                    else :#没暂停
                        self.paused_image = self.paused_nor_image
                else :                                      #鼠标不在暂停框内
                    if self.paused :#暂停
                        self.paused_image = self.resume_pressed_image
                    else :#没暂停
                        self.paused_image = self.pause_pressed_image
            elif self.rabbit.life == 0 :
                #pygame.mixer.music.stop()
                #pygame.mixer.stop()
                # if not recorded :
                #     recorded = True
                    # 读取历史最高分
                    #################################################
                    #################################################
                if not self.recorded :
                    self.recorded = True
                    try :
                        with open("record_score.txt" , "r") as f :
                            self.record_score = int(f.read())
                    except FileNotFoundError:
                        with open("record_score.txt" , "w") as f :
                            self.record_score=f.write(str(self.score))
                    with open("recordname.txt", "r") as f:
                        self.record_best_name=str(f.read())
                    if self.score > self.record_score :
                        with open("record_score.txt" , "w") as f :
                            f.write(str(self.score))
                        with open("record_login_user_name.txt" , "r") as f :
                            self.record_best_name = str(f.read())
                        with open("recordname.txt" , "w") as f :
                            f.write(str(self.record_best_name))
                self.update_score_name()


        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_w] or key_pressed[pygame.K_UP] :
            self.rabbit.move_up=True
        if key_pressed[pygame.K_s] or key_pressed[pygame.K_DOWN] :
            self.rabbit.move_down=True
        if key_pressed[pygame.K_a] or key_pressed[pygame.K_LEFT] :
            self.rabbit.move_left=True
        if key_pressed[pygame.K_d] or key_pressed[pygame.K_RIGHT] :
            self.rabbit.move_right = True


    def __check_collide(self):
    #检测子弹和敌机相撞并实现相应得分功能
        for b in self.rabbit.bullets :
            check_collide=\
                pygame.sprite.spritecollide(b,self.enemy_group,False,pygame.sprite.collide_mask)
            if check_collide:
                b.kill()
                for e in check_collide:
                        e.is_hit=True
                        e.energy-=1
                        if e.energy<=0:
                           e.energy=0#后面画血条会出现energy小于0出现画负血条
                           e.isDown=True
                           if e in self.small_enemy_group :
                               if e.index == 0 :
                                   #self.smalldestroy_sound.play()
                                   self.score+=SMALL_SCORE

                           elif e in self.mid_enemy_group:
                               if e.index == 0 :
                                    #self.middestroy_sound.play()
                                    self.double__supply(self.mid_enemy_group)
                                    self.score+=MID_SCORE

                           elif e in self.big_enemy_group :
                               if e.index == 0 :
                                   #self.bigdestroy_sound.play()
                                   self.bomb__supply(self.big_enemy_group)
                                   self.score += BIG_SCORE
                        else:
                           e.isDown=False
        # 我方飞机与敌方子弹碰撞检测
        rabbit_down = pygame.sprite.spritecollide(self.rabbit, self.Boss.bullets, False, pygame.sprite.collide_mask)
        if rabbit_down and self.rabbit.invincible == False:
            self.rabbit.isDown = True
            self.rabbit.invincible = True
            pygame.time.set_timer(INVINCIBLE_TIME, 3 * 1000)

        #我方飞机碰撞检测
        enemies_down =pygame.sprite.spritecollide(self.rabbit,self.enemy_group,False,pygame.sprite.collide_mask)
        if enemies_down and self.rabbit.invincible==False:
            self.rabbit.isDown = True
            self.rabbit.invincible=True
            pygame.time.set_timer(INVINCIBLE_TIME , 3 * 1000)

        for e in enemies_down:
            e.isDown = True
            if e in self.small_enemy_group:
                if e.index==0:
                    self.score += SMALL_SCORE

            elif e in self.mid_enemy_group:

                if e.index == 0 :

                    self.score +=MID_SCORE
                    self.double__supply(self.mid_enemy_group)

            elif e in self.big_enemy_group:
                if e.index == 0 :
                    #self.bigdestroy_sound.play()
                    self.bomb__supply(self.big_enemy_group)
                    self.score +=BIG_SCORE
                    e.index=1

        #我方飞机与双倍补给的碰撞检测
        double_supply_collide=pygame.sprite.spritecollide(self.rabbit,self.double_bullet_supply_group,True,pygame.sprite.collide_mask)
        if double_supply_collide:
            self.rabbit.isAvailable_Double_Bullet=True

        # 我方飞机与炸弹补给的碰撞检测
        bomb_supply_collide = pygame.sprite.spritecollide(self.rabbit, self.bomb_supply_group, True,pygame.sprite.collide_mask)
        if bomb_supply_collide:
            self.rabbit.isAvailable_Bomb_Bullet = True


        if len(self.enemy_group) == 0 :
            self.level+=0.3
            self.change_level()

    def __updata__font(self):

        score_text = self.my_font.render(str("兔叽得分: %s" % self.score) , True , WHITE).convert_alpha()
        score_text.set_alpha(170)

        life_text = self.my_font.render(str("兔命:%s") % self.rabbit.life , True , RED).convert_alpha()
        life_text.set_alpha(160)

        double_bullet_text = self.my_font.render(str("×%d") % self.rabbit.double_bullet_counts , True , RED)
        double_bullet_text.set_alpha(160)

        bomb_text = self.my_font.render(str("×%d") % self.rabbit.bomb_counts , True , RED)
        bomb_text.set_alpha(160)

        self.screen.blit(self.double_bullet_image , (self.screen_rect.width//2-30, self.screen_rect.height-75))
        self.screen.blit(score_text , (10 , 20))

        self.screen.blit(life_text , (self.screen_rect.width -150, self.screen_rect.height-55))

        self.screen.blit(double_bullet_text,(self.screen_rect.width//2, self.screen_rect.height-55))

        self.screen.blit(bomb_text, (self.screen_rect.width // 2-80, self.screen_rect.height - 55))


    def update_score_name(self):
        self.record_score_text = self.my_font.render("历史最高分:%d分是兔玩家：%s创造的 " %(self.record_score,self.record_best_name),True , WHITE)
        self.record_score_text_rect = self.record_score_text.get_rect()
        self.record_score_text_rect.left , self.record_score_text_rect.top = (SCREEN_RECT.width - self.gameover_text1_rect.width) // 2 , \
                                                SCREEN_RECT.height // 2 - 50
        self.screen.blit(self.record_score_text , self.record_score_text_rect)

        self.gameover_text2 = self.my_font.render(str(self.score) , True , WHITE)

        self.screen.blit(self.gameover_text1 , self.gameover_text1_rect)

        self.screen.blit(self.gameover_text2 , self.gameover_text2_rect)

        self.screen.blit(self.again_image , self.again_rect)

        self.screen.blit(self.gameover_image , self.gameover_rect)


    def __draw__hp__(self,group,energy):
        for each in group:
            pygame.draw.line(self.screen , BLACK , \
                             (each.rect.left , each.rect.top - 5) , \
                             (each.rect.right , each.rect.top - 5) , \
                             2)

            energy_remain = each.energy /energy
            if energy_remain > 0.2:
                energy_color = GREEN
            else :
                energy_color = RED
            pygame.draw.line(self.screen , energy_color , \
                             (each.rect.left , each.rect.top - 5) , \
                             (each.rect.left + each.rect.width * energy_remain , \
                              each.rect.top - 5) , \
                             2)

    def double__supply(self,group):
        num=randint(1,10)
        if num <=6:
            # 创建双倍补给精灵
            for each in group :
                if each.isDown==True:
                    double_bullet_supply=Bullet_Supply()
                    # 设置初始位置
                    double_bullet_supply.rect.centerx=each.rect.centerx
                    double_bullet_supply.rect.centery=each.rect.centery

                    ##################################################################################################
                    # 添加到精灵组
                    self.double_bullet_supply_group.add(double_bullet_supply)

    def bomb__supply(self, group):
        num = randint(1, 20)
        if num <=6:
            # 创建双倍补给精灵
            for each in group:
                if each.isDown == True:
                    bomb_supply = Bomb_Supply()
                    # 设置初始位置
                    bomb_supply.rect.centerx = each.rect.centerx
                    bomb_supply.rect.centery = each.rect.centery

                    ##################################################################################################
                    # 添加到精灵组
                    self.bomb_supply_group.add(bomb_supply)

    def __update_sprites(self):
        if self.rabbit.life > 0 and self.paused==False :
            self.bg_group.update()
            self.bg_group.draw(self.screen)
            self.enemy_group.update()
            self.enemy_group.draw(self.screen)

            self.__draw__hp__(self.mid_enemy_group,MID_ENERGY)
            self.__draw__hp__(self.big_enemy_group,BIG_ENERGY)
            self.__draw__hp__(self.boss01_group , BOSS01_ENERGY)

            self.myrabbit.update()
            self.myrabbit.draw(self.screen)
            if self.rabbit.invincible==True:
                self.rect.centerx= self.rabbit.rect.centerx
                self.rect.centery=self.rabbit.rect.centery
                self.screen.blit(self.image_protect , self.rect)

            self.rabbit.bullets.update()
            self.rabbit.bullets.draw(self.screen)
            self.Boss.bullets.update()
            self.Boss.bullets.draw(self.screen)

            self.double_bullet_supply_group.update()
            self.double_bullet_supply_group.draw(self.screen)

            self.bomb_supply_group.update()
            self.bomb_supply_group.draw(self.screen)
            self.__updata__font()
        if self.rabbit.life > 0:
           self.screen.blit(self.paused_image , self.paused_rect)


    @staticmethod
    def __game_over(self):
        pygame.quit()
        exit()



